package com.example.demo24_password.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

/**
 * PasswordEncoder 是一个接口，里边只有三个方法
 *      encode 方法用来对密码进行加密。
 *      matches 方法用来对密码进行比对。
 *      upgradeEncoding 表示是否需要对密码进行升级，默认为 false。
 * PasswordEncoder 中的 encode 方法，是我们在用户注册的时候手动调用。
 * matches 方法，则是由系统调用，默认是在 DaoAuthenticationProvider#additionalAuthenticationChecks 方法中调用的
 */
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 但是自己定义 PasswordEncoder 还是有些麻烦，特别是处理密码加盐问题的时候。
     * 所以在 Spring Security 中提供了 BCryptPasswordEncoder，使得密码加密加盐变得非常容易。
     * 只需要提供 BCryptPasswordEncoder 这个 Bean 的实例即可
     */
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
        inMemoryUserDetailsManager.createUser(User.withUsername("wangnian")
                .password("$2a$10$gu37aTffIrlw4Alaguhy3eIO6K39TSG4ekObXAdqx7Y8VYZSGpXIm").roles("admin").build());
        return super.userDetailsService();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .successHandler((request, response, authentication) -> {
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().write("登录成功");
                })
                .and().csrf().disable();
    }


    public static void main(String[] args) {
        System.out.println("new BCryptPasswordEncoder().encode(\"123\") = " + new BCryptPasswordEncoder().encode("123"));
    }
}
